(function (context){
    
    jCSV = ("function" == typeof jCSV)?jCSV:require('../jcsv.js');
    jsCSVTester = ("function" == typeof jsCSVTester)?jsCSVTester:require('../javascript-csv-tester.js');

    var tests = [];

    function structureTests(test){
        test.equal (typeof jCSV, "function", "jCSV is a function");
        test.equal (typeof jCSV.parse, "function", "jCSV.parse is a function");
        test.equal (typeof jCSV.toArrays, "function", "jCSV.toArrays is a function");
        var csvp = new jCSV();
        test.equal (typeof csvp, "object", "csvp is an object");
        test.equal (typeof csvp.write, "function", "csvp has 'write' method");
        test.equal (typeof csvp.writeAll, "function", "csvp has 'writeAll' method");
        test.equal (typeof csvp.close, "function", "csvp has 'close' method");
    }
    tests.push(structureTests); //comment this line to remove from the test

    function tokenizerTests(test){
        var ds = jCSV.init();
        jCSV.tokenize(ds,"a,b,c");
        test.deepEqual(ds.tokens,["a",",","b",",","c"],"a,b,c");
        ds = jCSV.init();
        jCSV.tokenize(ds,"a,b1,\"c\"");
        test.deepEqual(ds.tokens,["a",",","b1",",","\"c\""],"a,b1,\"c\"");
        ds = jCSV.init();
        jCSV.tokenize(ds,"a,\"b1\"\"\",\"\"\"cde\"\"f\"");
        test.deepEqual(ds.tokens,["a",",","\"b1\"\"\"",",","\"\"\"cde\"\"f\""],"a,\"b1\"\"\",\"\"\"cde\"\"f\"");
    }
    tests.push(tokenizerTests); //comment this line to remove from the test

    function bufferTests(test){
        bt = function(buffer,expected){
            var ds = jCSV.init(); 
            jCSV.tokenize(ds,buffer);
            jCSV.processTokens(ds);
            delete(ds.S);
            delete(ds.SE);
            delete(ds.SN);
            delete(ds.DQDQ);
            test.deepEqual(ds,expected, "bufferTests:"+buffer); 
        }
        bt("\"",       // "
                {
                "buffer": "\"",
                "data": [],
                "idx": 0,
                "pos": 0,
                "record": [],
                "state": 0,
                "tokens": []
                });
        bt("\"\"",     // ""
                {
                "buffer": "\"\"",
                "data": [],
                "idx": 1,
                "pos": 2,
                "prev": 0,
                "record": [],
                "state": 3,
                "tokens": [ "\"\"" ]
                });
        bt("\"\"\"",   // """
                {
                "buffer": "\"\"\"",
                "data": [],
                "idx": 1,
                "pos": 2,
                "prev": 0,
                "record": [],
                "state": 3,
                "tokens": [ "\"\"" ]
                });
        bt("\"\"\"\"", // """"
                {
                "buffer": "\"\"\"\"",
                "data": [],
                "idx": 1,
                "pos": 4,
                "prev": 0,
                "record": [],
                "state": 3,
                "tokens": [ "\"\"\"\"" ]
                });
        bt("\"a",      // "a
                {
                "buffer": "\"a",
                "data": [],
                "idx": 0,
                "pos": 0,
                "record": [],
                "state": 0,
                "tokens": []
                });
        bt("\"\r",     // "\r
                {
                "buffer": "\"\r",
                "data": [],
                "idx": 0,
                "pos": 0,
                "record": [],
                "state": 0,
                "tokens": []
                });
        bt("\"\n",     // "\n
                {
                "buffer": "\"\n",
                "data": [],
                "idx": 0,
                "pos": 0,
                "record": [],
                "state": 0,
                "tokens": []
                });
        bt("\",",      // ",
                { 
                "buffer": "\",",
                "data": [],
                "idx": 0,
                "pos": 0,
                "record": [],
                "state": 0,
                "tokens": []
                });
        bt("a,\"\"b",      // a,""b
                { 
                "buffer": "a,\"\"b",
                "data": [],
                "idx": 4,
                "pos": 5,
                "prev": 3,
                "record": [ "a" ],
                "state": 7,
                "tokens": [ "a", ",", "\"\"", "b" ]
                });
        bt("a,\"\"\"",      // a,"""
                { 
                "buffer": "a,\"\"\"",
                "data": [],
                "idx": 3,
                "pos": 4,
                "prev": 1,
                "record": [ "a" ],
                "state": 3,
                "tokens": [ "a", ",", "\"\"" ]
                });
        bt("a,,\"b",      // a,,"b
                { 
                "buffer": "a,,\"b",
                "data": [],
                "idx": 3,
                "pos": 3,
                "prev": 1,
                "record": [ "a", "" ],
                "state": 1,
                "tokens": [ "a", ",", "," ]
                });
    }
    tests.push(bufferTests); //comment this line to remove from the test

    _debug_result = null;
    _debug_expected = null;

    function toArraysTests(test){
        
        var ds = jCSV.toArrays("a,b,c\r\nd,e,\"a\"\"b\"");
        test.deepEqual(ds.data,[["a","b","c"],["d","e","a\"b"]],"a,b,c\\r\\nd,e,\"a\"\"b\"");

        ds = jCSV.toArrays("a,b,c\r\nd,e,f");
        test.deepEqual(ds.data,[["a","b","c"],["d","e","f"]],"a,b,c\\r\\nd,e,f");
/**/
        var testCSV = (jsCSVTester.genCSVWithMetric({rows:1000,cols:20,max:50,esc:0.5}));
        var expected = testCSV.data;
        var result = jCSV.toArrays(testCSV.text).data;
        _debug_result = result;
        _debug_expected = expected;
        test.deepEqual(result, expected, "Generated CSV parse with");
/**/
    }
    tests.push(toArraysTests); //comment this line to remove from the test

    function toArraysBufferedTests(test){
        
        var ds = jCSV.toArrays("a,b,c\r\nd,e,");
        test.deepEqual(ds.data,[["a","b","c"],["d","e",""]],"a,b,c\\r\\nd,e");

        var testCSV = (jsCSVTester.genCSVWithMetric({rows:100,cols:20,max:50,esc:0.9}));
        var expected = testCSV.data;
        var result = jCSV.toArrays(testCSV.text,{max:1}).data;
        _debug_result = result;
        _debug_expected = expected;
        test.deepEqual(result, expected, "Buffered Generated CSV parse with");
    }
    tests.push(toArraysBufferedTests); //comment this line to remove from the test

    function testRunner(test){
        for(var i=0; i < tests.length; ++i){
            tests[i](test);
        }
    }

    context.testJCSV = function(test){
        testRunner(test);
        if(test.done){test.done();}
    };
})(('object' == typeof exports)?module.exports:this);
